Linking Plots Using Brush Interval Selector

Details on how to use the brush interval selector can be found in this notebook.

Brush interval selectors can be used where continuous updates are not desirable (for example, in callbacks performing slower computations)

The boolean trait brushing can be used to control continuous updates in the BrushSelector. brushing will be set to False when the interval selector is not brushing. We can register callbacks by listening to the brushing trait of the brush selector. We can check the value of brushing trait in the callback and perform updates only at the end of brushing.

Let's now look at an example of linking a time series plot to a scatter plot using a BrushIntervalSelector


In [ ]:
import numpy as np

In [ ]:
from ipywidgets import Layout, HTML, VBox
import bqplot.pyplot as plt

Let's set up an interval selector on a figure containing two time series plots. The interval selector can be activated by clicking on the figure


In [ ]:
from bqplot.interacts import BrushIntervalSelector

y1, y2 = np.random.randn(2, 200).cumsum(axis=1) # two simple random walks

fig_layout = Layout(width='900px', height='500px')
time_series_fig = plt.figure(layout=fig_layout)
line = plt.plot([y1, y2])

# create a fast interval selector by passing in the X scale and the line mark on which the selector operates
intsel = BrushIntervalSelector(marks=[line], scale=line.scales['x'])
time_series_fig.interaction = intsel # set the interval selector on the figure

Let's now create a scatter plot of the two time series and stack it below the time series plot using a VBox


In [ ]:
scat_fig = plt.figure(layout=fig_layout, 
                      animation_duration=750,
                      title='Scatter of time series slice selected by the interval selector')
# set the x and y attributes to the y values of line.y
scat = plt.scatter(*line.y, colors=['red'], stroke='black')

In [ ]:
# define a callback for the interval selector
def update_scatter(*args):
    brushing = intsel.brushing
    
    # update scatter *only* when the interval selector
    # is not brushing to prevent continuous updates
    if not brushing:
        # interval selector is active
        if line.selected is not None:
            # get the start and end indices of the interval
            start_ix, end_ix = line.selected[0], line.selected[-1]
        else:  # interval selector is *not* active
            start_ix, end_ix = 0, -1
            
        #update the x and y attributes of the scatter by slicing line.y
        with scat.hold_sync():
            scat.x, scat.y = line.y[:, start_ix:end_ix]

# register the callback with brushing trait of interval selector
intsel.observe(update_scatter, 'brushing')

In [ ]:
help_label = HTML('<div style="color: blue; font-size: 16px; margin:20px 0px 0px 50px">\
                  Brush on the time series plot to activate the interval selector</div>')
VBox([help_label, time_series_fig, scat_fig])